﻿Imports Persistencia
Imports System.Math
Imports DSControlePadrao
Public Class ctrProposta
    Inherits ctrPadrao
#Region "Variáveis de Instância"

    Private _dsProposta As DataSet
    Private _dtbLog As New DataTable

    Private objRegiao As New ctrRegioes
    Private objMarca As New ctrMarca
    Private objProdutos As New ctrProduto
    Private objForma As New ctrForma
    Private objImposto As New ctrImposto
    Private objTerceiros As New ctrTerceiros
    Private objProposta As New perPropostas
    Private objDespesas As New ctrDespesa

#End Region

#Region "Enumerações"

    Public Enum eTipoMercado As Int32
        MercadoInterno = 0
        MercadoExterno = 1
    End Enum

    Public Enum eSegmento As Int32
        SiderurgiaMI = 12
        IndustrialMI = 33
        SiderurgiaME = 50
        IndustrialME = 51
    End Enum

    Public Enum eStatus As Int32
        EmAnalise = 0
        Aceita = 1
        Recusada = 2
        Aprovada = 3
        Cancelada = 4
    End Enum

    Public Enum eCondicaoVenda As Int32
        CIP = 0
        FCA = 1
    End Enum


    Public Enum eMensagens As Int32
        CLIENTE_OBRIGATORIO = 0
        SEGMENTO_OBRIGATORIO = 1
        VALIDADE_INVALIDA = 2
        PRODUTOS_QUANTIDADE_INVALIDA = 3
        PRODUTOS_VALOR_INVALIDO = 4
        CONDICAO_COMERCIAL_INVALIDA = 5
        DATA_ENTREGA_AANTERIOR_DATA_PROPOSTA = 6
        FRETE_NAO_INFORMADO = 7
        OUTRA_RECEITA_NAO_INFORMADA = 8
    End Enum

    Public Enum eTabelas As Int32
        REGIAO = 0
        PRODUTOS = 1
        FORMA = 2
        TERCEIROS = 3
        OUTRAS_DESPESAS = 4
    End Enum

    Public Enum eReceitaBruta
        RefratariosFormas = 0
        MateriaisTerceiros = 1
    End Enum

    Public Enum eCustosProposta
        RefratariosFormas = 0
        MateriaisTerceiros = 1
    End Enum

#End Region

    Public WriteOnly Property dsproposta
        Set(ByVal value)
            _dsProposta = value
        End Set

    End Property

    Public Property CodProposta As Int32
    Public Property RevProposta As Int32

    Public StatusProposta As String() = {"Em Análise", "Aceita", "Recusada", "Aprovada", "Cancelada"}
    Public ReceitaBruta As String() = {"Refratários e Fôrmas", "Materiais de terceiros", "Serviços"}
    Public CustoProposa As String() = {"Produtos Vendidos", "Materiais de terceiros"}

    Public Mensagens As String() = {"Cliente não selecionado.",
                                     "Segmento não selecionado.",
                                     "Validade inválida.",
                                     "Produtos com quantidade inválida.",
                                     "Produtos com valor inválido.",
                                     "Condição comercial não informada.",
                                     "Data de entrega inválida.",
                                     "Frete não calculado.",
                                     "Outras receitas não informadas."}



    ReadOnly Property descricaoReceitaBruta(ByVal tipoReceita As eReceitaBruta) As String
        Get
            Return ReceitaBruta(tipoReceita)
        End Get
    End Property

    ReadOnly Property descricaoCustoProposta(ByVal tipoCusto As eCustosProposta) As String
        Get
            Return CustoProposa(tipoCusto)
        End Get
    End Property

    Public Function retornarDataSet()
        Dim dsProposta As New DataSet

        Try
            dsProposta.Tables.Add(Me.objRegiao.retornarDatRegioes.Copy)
            dsProposta.Tables.Add(Me.objProdutos.retornarDatProdutos.Copy)
            dsProposta.Tables.Add(Me.objForma.retornarDatForma.Copy)
            dsProposta.Tables.Add(Me.objTerceiros.retornarDatTerceiros.Copy)
            dsProposta.Tables.Add(Me.objDespesas.retornarDatOutrasDespesas.Copy)

            Return dsProposta

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro no método retornarDataSet." & _
                                    Environment.NewLine & ex.Message)


        End Try

    End Function

    Public Function calcularFrete(ByVal dValor As Double, ByVal dPeso As Double) As Double

        Try
            Return dValor * dPeso

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao calcular o frete. " & _
                                    Environment.NewLine & ex.Message)


        End Try

    End Function

    Public Function calcularLucroBruto(ByVal dPrecoTotal As Decimal, ByVal dFormaAParte As Decimal, ByVal dCustoTotal As Decimal, ByVal dICMS As Decimal) As Decimal
        Dim dImposto As Decimal = 0

        Try
            dImposto = objImposto.calcularImposto(dPrecoTotal, dFormaAParte, dICMS)

            Return Decimal.Round(dPrecoTotal + dFormaAParte - dImposto - dCustoTotal, 2)

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao calcular o lucro bruto. " & _
                                    Environment.NewLine & ex.Message)


        End Try

    End Function

    Public Function calcularReceitaLiquida(ByVal dPrecoTotal As Decimal, ByVal dFormaAParte As Decimal, ByVal dICMS As Decimal) As Decimal
        Dim dImposto As Decimal

        Try
            dImposto = Me.objImposto.calcularImposto(dPrecoTotal, dFormaAParte, dICMS)

            Return Decimal.Round(dPrecoTotal + dFormaAParte - dImposto, 2)

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao calcular a Receita Líquida. " & _
                                    Environment.NewLine & ex.Message)


        End Try
    End Function

    Public Function calcularLucroOperacional(ByVal dPrecoTotal As Decimal, ByVal dFormaAParte As Decimal,
                                             ByVal dFrete As Decimal, ByVal dRoyalties As Decimal,
                                             ByVal dComissao As Decimal, ByVal dCustoTotal As Decimal, ByVal dICMS As Decimal) As Decimal

        Dim dImposto As Decimal
        Dim dAjuste As Decimal

        Try

            dImposto = objImposto.calcularImposto(dPrecoTotal, dFormaAParte, dICMS)
            dAjuste = objImposto.retornarAjusteImposto(dICMS)

            Return Decimal.Round(dPrecoTotal + dFormaAParte - (dFormaAParte - dAjuste) - dImposto - dFrete - dRoyalties - dComissao - dCustoTotal, 2)

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao calcular Lucro Operacional. " & _
                                    Environment.NewLine & ex.Message)


        End Try

    End Function

    Public Function calcularComissao(ByVal dPrecoTotal As Decimal, ByVal dFormaAParte As Decimal, ByVal dComissao As Decimal, ByVal dICMS As Decimal) As Decimal
        Dim dImposto As Decimal

        Try
            dImposto = objImposto.calcularImposto(dPrecoTotal, dFormaAParte, dICMS)

            Return Decimal.Round((dComissao / 100) * (dPrecoTotal - dImposto), 2)

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao calcular a comissão. " & _
                                    Environment.NewLine & ex.Message)


        End Try
    End Function

    Public Function calcularEBTIDA(ByVal dEbtida_Vendas As Decimal, ByVal dEbtida_Adm As Decimal, ByVal dEbtida_Depreciacao As Decimal,
                                   ByVal dReceitaLiquida As Decimal, ByVal dValorCusto As Decimal) As Decimal
        Dim dEbtida_DV As Decimal = 0
        Dim dEbtida_DA As Decimal = 0
        Dim dEbtida_DP As Decimal = 0

        Try
            If dEbtida_Vendas > 0 And dEbtida_Adm > 0 And dEbtida_Depreciacao > 0 Then
                dEbtida_DV = Decimal.Round(dReceitaLiquida * (dEbtida_Vendas / 100), 2)
                dEbtida_DA = Decimal.Round(dReceitaLiquida * (dEbtida_Adm / 100), 2)
                dEbtida_DP = Decimal.Round(dReceitaLiquida * (dEbtida_Depreciacao / 100), 2)

            End If

            Return Decimal.Round(dReceitaLiquida - dValorCusto - dEbtida_DV - dEbtida_DA + dEbtida_Depreciacao, 2)


        Catch ex As Exception

        End Try
    End Function

    Public Function calcularEvolucaoCusto(ByVal dtDataProposta As Date, ByVal dtDataEntrega As Date, ByVal dValorCusto As Decimal, ByVal dPercEvolucao As Decimal) As Decimal
        Dim iMeses As Int32
        Dim dFatorEvolucao As Decimal

        Try
            iMeses = DateDiff(DateInterval.Month, dtDataProposta, dtDataEntrega)
            dFatorEvolucao = Pow((dPercEvolucao + 100) / 100, iMeses)

            Return dValorCusto * dFatorEvolucao

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao calcular a evolução do custo. " & _
                                    Environment.NewLine & ex.Message)

        End Try

    End Function

    Public Function gravarProposta(ByVal iCodProposta As Int32,
                                  ByVal iRevProposta As Int32,
                               ByVal sCodCliente As String,
                               ByVal dtDataProposta As Date,
                               ByVal iSegmento As Int32,
                               ByVal sSolicitacao As String,
                               ByVal iValProposta As Int32,
                               ByVal sReferencia As String,
                               ByVal iModalidadeVenda As Int32,
                               ByVal iCondicaoVenda As Int32,
                               ByVal dtDataEntrega As Date,
                               ByVal bSemImposto As Boolean,
                               ByVal dEBTIDA_DespVenda As Double,
                               ByVal dEBTIDA_DespAdm As Double,
                               ByVal dEBTIDA_Depreciacao As Double,
                               ByVal dEvolCusto As Double,
                               ByVal dComissao As Double,
                               ByVal sCodFrete As String,
                               ByVal iTipoExp As Int32,
                               ByVal dValorFrete As Decimal,
                               ByVal dICMS As Double,
                               ByVal dPISCOFINS As Double,
                               ByVal iStatus As Int32,
                               ByVal iMercado As Int32,
                               ByVal dValorProposta As Decimal,
                               ByVal dsProposta As DataSet) As Boolean

        Dim bRetorno As Boolean = False
        Dim dValorOutraDespesa As Decimal
        Dim objRegiao As New perRegiao
        Dim objProdutosProposta As New perProdutoProposta
        Dim objFormaProposta As New perFormaProposta
        Dim objTerceirosProposta As New perTerceiroProposta
        Dim objOutrasDepesasProposta As New perOutrasDespesasProposta


        Try
            If iCodProposta > 0 Then
                iRevProposta = objProposta.retornarRevProposta(iCodProposta)
            End If

            Me.CodProposta = objProposta.inserirProposta(iCodProposta,
                                                         iRevProposta,
                                                         sCodCliente,
                                                         dtDataProposta.ToShortDateString,
                                                         iSegmento,
                                                         sSolicitacao,
                                                         iValProposta,
                                                         sReferencia,
                                                         iModalidadeVenda,
                                                         iCondicaoVenda,
                                                         dtDataEntrega.ToShortDateString,
                                                         bSemImposto, dEBTIDA_DespVenda, dEBTIDA_DespAdm,
                                                         dEBTIDA_Depreciacao, dEvolCusto, dComissao,
                                                         sCodFrete, iTipoExp, dValorFrete, dICMS, dPISCOFINS,
                                                         iStatus, iMercado, dValorProposta)

            'Regiões
            For Each drRegioes As DataRow In dsProposta.Tables(eTabelas.REGIAO).Rows
                objRegiao.inserirRegiaoProposta(drRegioes.Item(ctrRegioes.eColunasTabela.COD_REGIAO),
                                                Me.CodProposta, iRevProposta,
                                                drRegioes.Item(ctrRegioes.eColunasTabela.DESC_REGIAO), "")
            Next

            'Produto
            For Each drProduto As DataRow In dsProposta.Tables(eTabelas.PRODUTOS).Rows
                objProdutosProposta.inserirProdutoProposta(Me.CodProposta, iRevProposta,
                                                           drProduto.Item(ctrProduto.eColunasProdutos.COD_PRODUTO),
                                                           drProduto.Item(ctrProduto.eColunasProdutos.COD_REGIAO),
                                                           0,
                                                           drProduto.Item(ctrProduto.eColunasProdutos.FORMA),
                                                           drProduto.Item(ctrProduto.eColunasProdutos.QUANTIDADE),
                                                           drProduto.Item(ctrProduto.eColunasProdutos.VALOR_MARCA),
                                                           drProduto.Item(ctrProduto.eColunasProdutos.CUSTO_MARCA),
                                                           Conversao.ToDecimal(drProduto.Item(ctrProduto.eColunasProdutos.ROYALTIES)))
            Next

            'Forma 
            For Each drForma As DataRow In dsProposta.Tables(eTabelas.FORMA).Rows
                objFormaProposta.inserirFormaProposta(Me.CodProposta, iRevProposta,
                                                      drForma.Item(ctrForma.eColunasForma.COD_REGIAO),
                                                      drForma.Item(ctrForma.eColunasForma.COD_PRODUTO),
                                                      drForma.Item(ctrForma.eColunasForma.FORMA),
                                                      drForma.Item(ctrForma.eColunasForma.VALOR_FORMA),
                                                      drForma.Item(ctrForma.eColunasForma.DILUIR))
            Next

            'Terceiros
            For Each drTerceiro As DataRow In dsProposta.Tables(eTabelas.TERCEIROS).Rows
                objTerceirosProposta.inserirTerceirosProposta(Me.CodProposta, iRevProposta,
                                                              drTerceiro.Item(ctrTerceiros.eColunasTerceiros.COD_REGIAO),
                                                              drTerceiro.Item(ctrTerceiros.eColunasTerceiros.PRODUTO),
                                                              0,
                                                              drTerceiro.Item(ctrTerceiros.eColunasTerceiros.QUANTIDADE),
                                                              drTerceiro.Item(ctrTerceiros.eColunasTerceiros.CUSTO_UNITARIO),
                                                              drTerceiro.Item(ctrTerceiros.eColunasTerceiros.BDI),
                                                              drTerceiro.Item(ctrTerceiros.eColunasTerceiros.PRECO_UNITARIO))
            Next

            'Outras Despesas
            For Each drDespesa As DataRow In dsProposta.Tables(eTabelas.OUTRAS_DESPESAS).Rows
                dValorOutraDespesa = Conversao.ToDecimal(drDespesa.Item(ctrDespesa.eColunasDespesa.VALOR))
                If dValorOutraDespesa > 0 Then
                    objOutrasDepesasProposta.inserirOutrasDespesasProposta(Me.CodProposta, iRevProposta,
                                                                           drDespesa.Item(ctrDespesa.eColunasDespesa.ID_DESPESA),
                                                                           dValorOutraDespesa,
                                                                           Conversao.ToBoolean(drDespesa.Item(ctrDespesa.eColunasDespesa.GERAR_RECEITA)),
                                                                           Conversao.ToDecimal(drDespesa.Item(ctrDespesa.eColunasDespesa.VALOR_RECEITA)))
                End If
            Next

            Me.RevProposta = iRevProposta

            bRetorno = True

            Return bRetorno

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao gravar a proposta. " & _
                                    Environment.NewLine & ex.Message)


        End Try
    End Function

    Public Function retornarNomeclaturaPorSegmento(ByVal iSegmento As eSegmento) As String
        Dim sRetorno As String = ""

        Try

            Select Case iSegmento
                Case eSegmento.IndustrialME, eSegmento.IndustrialMI
                    sRetorno = "Industrial"
                Case eSegmento.SiderurgiaME, eSegmento.SiderurgiaMI
                    sRetorno = "Siderurgia"
            End Select

            Return sRetorno

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao retornar a nomeclatura do segmento. " & _
                                    Environment.NewLine & ex.Message)

        End Try

    End Function

    Public Function validarProposta(ByVal sCodCliente As String,
                               ByVal iSegmento As Int32,
                               ByVal iValProposta As Int32,
                               ByVal iCondicaoVenda As eCondicaoVenda,
                               ByVal sCondicaoComercial As String,
                               ByVal dValorFrete As Decimal,
                               ByVal dtDataEntrega As Date,
                               ByVal dEBTIDA_DespVenda As Double,
                               ByVal dEBTIDA_DespAdm As Double,
                               ByVal dEBTIDA_Depreciacao As Double,
                               ByVal dEvolCusto As Double,
                               ByVal dComissao As Double,
                               ByVal dICMS As Double,
                               ByVal dPISCOFINS As Double,
                               ByVal dsProposta As DataSet) As Boolean

        Dim bRetorno As Boolean = False

        Try
            If sCodCliente = String.Empty Then
                MyBase.adicionarMensagensValidacao(eMensagens.CLIENTE_OBRIGATORIO,
                                                   ctrPadrao.eTipoLog.ERRO,
                                                   Mensagens(eMensagens.CLIENTE_OBRIGATORIO))
            End If

            If iSegmento = 0 Then
                MyBase.adicionarMensagensValidacao(eMensagens.SEGMENTO_OBRIGATORIO,
                                                   ctrPadrao.eTipoLog.ERRO,
                                                   Mensagens(eMensagens.SEGMENTO_OBRIGATORIO))
            End If

            If iValProposta <= 0 Then
                MyBase.adicionarMensagensValidacao(eMensagens.VALIDADE_INVALIDA,
                                                   ctrPadrao.eTipoLog.ERRO,
                                                   Mensagens(eMensagens.VALIDADE_INVALIDA))
            End If

            If sCondicaoComercial = String.Empty Then
                MyBase.adicionarMensagensValidacao(eMensagens.CONDICAO_COMERCIAL_INVALIDA,
                                                   ctrPadrao.eTipoLog.AVISO,
                                                   Mensagens(eMensagens.CONDICAO_COMERCIAL_INVALIDA))
            End If

            If iCondicaoVenda = eCondicaoVenda.CIP And dValorFrete = 0 Then
                MyBase.adicionarMensagensValidacao(eMensagens.FRETE_NAO_INFORMADO,
                                                   ctrPadrao.eTipoLog.AVISO,
                                                   Mensagens(eMensagens.FRETE_NAO_INFORMADO))
            End If

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro ao validar a proposta. " & _
                        Environment.NewLine & ex.Message)
        End Try

    End Function

    Public Function retornarPropostas(ByVal iCodProposta As Int32, ByVal iRevisao As Int32,
                                     ByVal dtInicioProposta As Date, ByVal dtFimProposta As Date,
                                     ByVal dtInicioValidade As Date, ByVal dtFimValidade As Date,
                                     ByVal sCodCliente As String, ByVal iStatus As Int32,
                                     ByVal dtAprovacao As Date) As DataTable
        Try

            Return objProposta.retornarPropostas(iCodProposta, iRevisao,
                                                 dtInicioProposta, dtFimProposta,
                                                 dtInicioValidade, dtFimValidade,
                                                 sCodCliente, iStatus,
                                                 dtAprovacao)

        Catch ex As Exception
            Throw New Exception("Ocorreu um erro ao retornar propostas. " & _
                        Environment.NewLine & ex.Message)
        End Try

    End Function

    Public Function retornarCodProposta(ByVal sCodCotacao As String) As Int32
        Dim sCotacao As String()
        Dim iCodProposta As Int32

        Try
            sCotacao = sCodCotacao.Split("-")
            If sCotacao.Length = 1 Then
                iCodProposta = sCotacao(0)
            Else
                iCodProposta = Conversao.ToInt32(sCotacao(1))
            End If

            Return iCodProposta

        Catch ex As Exception
            Throw New Exception("Ocorreu um erro ao retornar o código da proposta. " & _
                        Environment.NewLine & ex.Message)
        End Try
    End Function

    Public Function retornarPropostaDetalhes(ByVal icodProposta As Int32, ByVal iRevProposta As Int32) As DataRow
        Try
            Return objProposta.retornarPropostaDetalhes(icodProposta, iRevProposta)

        Catch ex As Exception

            Throw New Exception("Ocorreu um erro no método retornarPropostaDetalhes." & _
                                Environment.NewLine & ex.Message)

        End Try

    End Function

End Class
